import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:get/get.dart';
import 'package:series_play/comm/base/base_list_controller.dart';
import 'package:series_play/generated/assets.dart';
import 'package:series_play/widget/app_color.dart';
import 'package:series_play/widget/app_image.dart';
import 'package:series_play/widget/app_text.dart';

/// 刷新加载listview
class AppRefreshListView extends StatefulWidget {
  const AppRefreshListView({
    required this.listController,
    this.itemCount,
    this.onRefresh,
    this.onLoad,
    this.separatorBuilder,
    this.listScrollController,
    required this.itemBuilder,
    this.padding,
    this.emptyButtonOnTap,
    this.emptyButtonDataBuilder,
    this.emptyDataBuilder,
    super.key,
  });

  final NullableIndexedWidgetBuilder itemBuilder;
  final RefreshCallback? onRefresh;
  final RefreshCallback? onLoad;
  final IndexedWidgetBuilder? separatorBuilder;
  final ScrollController? listScrollController;
  final int? itemCount;
  final BaseListController listController;
  final EdgeInsetsGeometry? padding;

  final RefreshViewStringBuilder? emptyDataBuilder;
  final RefreshViewStringBuilder? emptyButtonDataBuilder;
  final VoidCallback? emptyButtonOnTap;

  @override
  State<AppRefreshListView> createState() => _AppRefreshListViewState();
}

class _AppRefreshListViewState<C extends BaseListController>
    extends AppRefreshState<AppRefreshListView> {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return RefreshIndicator(
      color: AppColor.primary,
      key: refreshViewKey,
      onRefresh: widget.listController.onRefreshing,
      child: Obx(
        () => ListView.separated(
          controller: scrollController,
          padding: widget.padding,
          itemBuilder: (context, index) {
            // 上层分发item
            return getItem(index);
          },
          separatorBuilder: (context, index) {
            return widget.separatorBuilder?.call(context, index) ??
                SizedBox(height: 0);
          },
          itemCount: _getItemCount(),
        ),
      ),
    );
  }

  int _getItemCount() {
    if (listController.isEmptyData.value) {
      return 1;
    }
    return listController.dataList.length + (canLoadMore() ? 1 : 0);
  }

  @override
  Widget getDefaultItem(index) {
    return widget.itemBuilder(context, index) ?? Container();
  }

  @override
  ScrollController createController() {
    return widget.listScrollController ?? ScrollController();
  }

  @override
  BaseListController findListController() {
    return widget.listController;
  }

  @override
  bool canLoadMore() {
    return widget.onLoad != null;
  }

  @override
  void loadMore() {
    super.loadMore();
    widget.onLoad?.call();
  }

  @override
  RefreshViewStringBuilder? getEmptyDataBuilder() => widget.emptyDataBuilder;

  @override
  RefreshViewStringBuilder? getEmptyButtonDataBuilder() => widget.emptyButtonDataBuilder;

  @override
  VoidCallback? getEmptyButtonOnTap() => widget.emptyButtonOnTap;
}

/// 刷新加载gridview
class AppRefreshGridView extends StatefulWidget {
  const AppRefreshGridView({
    required this.listController,
    required this.crossAxisCount,
    required this.mainAxisSpacing,
    required this.crossAxisSpacing,
    this.itemCount,
    this.onRefresh,
    this.onLoad,
    this.listScrollController,
    required this.itemBuilder,
    this.padding,
    this.emptyDataBuilder,
    this.emptyButtonDataBuilder,
    this.emptyButtonOnTap,
    super.key,
  });

  final int crossAxisCount;
  final double mainAxisSpacing;
  final double crossAxisSpacing;
  final NullableIndexedWidgetBuilder itemBuilder;
  final RefreshCallback? onRefresh;
  final RefreshCallback? onLoad;
  final ScrollController? listScrollController;
  final int? itemCount;
  final BaseListController listController;
  final EdgeInsetsGeometry? padding;

  final RefreshViewStringBuilder? emptyDataBuilder;
  final RefreshViewStringBuilder? emptyButtonDataBuilder;
  final VoidCallback? emptyButtonOnTap;

  @override
  State<AppRefreshGridView> createState() => _AppRefreshGridViewState();
}

class _AppRefreshGridViewState extends AppRefreshState<AppRefreshGridView> {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return RefreshIndicator(
      color: AppColor.primary,
      key: refreshViewKey,
      onRefresh: widget.listController.onRefreshing,
      child: CustomScrollView(
        controller: scrollController,
        physics: AlwaysScrollableScrollPhysics(),
        slivers: [
          Obx(() {
            // 空数据
            if (listController.isEmptyData.value) {
              return SliverToBoxAdapter(child: buildEmptyView());
            }
            // 列表
            return SliverPadding(
              padding: widget.padding ?? const EdgeInsets.all(0),
              sliver: SliverAlignedGrid.count(
                crossAxisCount: widget.crossAxisCount,
                mainAxisSpacing: widget.mainAxisSpacing,
                crossAxisSpacing: widget.crossAxisSpacing,
                itemBuilder: (context, index) {
                  // 直接返回普通item
                  return getDefaultItem(index);
                },
                itemCount: _getItemCount(),
              ),
            );
          }),
          // 始终占位
          SliverToBoxAdapter(child: buildFooterView()),
        ],
      ),
    );
  }

  int _getItemCount() {
    return listController.dataList.length;
  }

  @override
  Widget getDefaultItem(index) {
    return widget.itemBuilder(context, index) ?? Container();
  }

  @override
  ScrollController createController() {
    return widget.listScrollController ?? ScrollController();
  }

  @override
  BaseListController findListController() {
    return widget.listController;
  }

  @override
  bool canLoadMore() {
    return widget.onLoad != null;
  }

  @override
  void loadMore() {
    super.loadMore();
    widget.onLoad?.call();
  }

  @override
  RefreshViewStringBuilder? getEmptyDataBuilder() => widget.emptyDataBuilder;

  @override
  RefreshViewStringBuilder? getEmptyButtonDataBuilder() => widget.emptyButtonDataBuilder;

  @override
  VoidCallback? getEmptyButtonOnTap() => widget.emptyButtonOnTap;

}

abstract class AppRefreshState<T extends StatefulWidget> extends State<T>
    with AutomaticKeepAliveClientMixin {
  late ScrollController scrollController;

  late BaseListController listController;

  GlobalKey refreshViewKey = GlobalKey();

  Size? _refreshViewSize;

  @override
  void initState() {
    super.initState();
    scrollController = createController();
    listController = findListController();
    listenScroll();
  }

  ScrollController createController();

  BaseListController findListController();

  listenScroll() {
    scrollController.addListener(() {
      if (scrollController.position.pixels >=
          scrollController.position.maxScrollExtent - 50) {
        if (canLoadMore() && !listController.isNoMoreData.value) {
          loadMore();
        }
      }
    });
  }

  bool canLoadMore();

  void loadMore() {
    if (!canLoadMore()) {
      return;
    }
    if (listController.isLoading.value || listController.isRefreshing.value) {
      return;
    }
  }

  getItem(int index) {
    if (listController.isEmptyData.value) {
      return buildEmptyView();
    } else if (canLoadMore() && index == listController.dataList.length) {
      return buildFooterView();
    }
    return getDefaultItem(index);
  }

  Widget buildEmptyView() {
    final size = getRefreshViewSize();
    final emptyData = getEmptyDataBuilder();
    final emptyButtonData = getEmptyButtonDataBuilder();
    final child = Column(
      children: [
        40.verticalSpace,
        AppImage(Assets.imagesImgEmptyData, width: 110, height: 56),
        18.5.verticalSpace,
        AppText(
          emptyData == null ? '暂无数据' : emptyData.call(context),
          color: AppColor.white_40,
        ),
        50.verticalSpace,
        emptyButtonData == null
            ? Container()
            : GestureDetector(
                onTap: getEmptyButtonOnTap,
                child: Container(
                  height: 40.w,
                  padding: const EdgeInsets.symmetric(horizontal: 45).w,
                  decoration: BoxDecoration(
                    color: const Color(0xFF393D45),
                    borderRadius: BorderRadius.circular(6).r,
                  ),
                  child: AppText(
                    emptyButtonData.call(context),
                    color: AppColor.white,
                  ),
                ),
              ),
      ],
    );

    return Container(
      width: size.width,
      height: size.height,
      alignment: Alignment.center,
      child: child,
    );
  }

  Widget buildFooterView() {
    return Obx(() {
      if (listController.isEmptyData.value) {
        return Container();
      }

      if (listController.isNoMoreData.value) {
        return Container(
          padding: const EdgeInsets.all(10).r,
          alignment: Alignment.center,
          child: AppText('暂无更多', color: AppColor.white_20, fontSize: 14),
        );
      }
      if (listController.isLoading.value) {
        return Container(
          padding: const EdgeInsets.all(10).r,
          alignment: Alignment.center,
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              SpinKitRing(
                lineWidth: 2,
                color: Theme.of(context).primaryColor,
                size: 16,
              ),
              8.horizontalSpace,
              AppText('加载中...', color: AppColor.white_20, fontSize: 14),
            ],
          ),
        );
      }
      // 占位
      return Container(
        padding: const EdgeInsets.all(10).r,
        alignment: Alignment.center,
        child: AppText('', color: AppColor.white_20, fontSize: 14),
      );
    });
  }

  Size getRefreshViewSize() {
    if (_refreshViewSize != null) {
      return _refreshViewSize!;
    }
    RenderBox? listViewBox =
        refreshViewKey.currentContext?.findRenderObject() as RenderBox?;
    _refreshViewSize = listViewBox == null
        ? Size.zero
        : (listViewBox.hasSize ? (listViewBox.size) : Size.zero);
    return _refreshViewSize!;
  }

  Widget getDefaultItem(index);

  RefreshViewStringBuilder? getEmptyDataBuilder() => null;

  RefreshViewStringBuilder? getEmptyButtonDataBuilder() => null;

  VoidCallback? getEmptyButtonOnTap() => null;

  @override
  void dispose() {
    super.dispose();
    scrollController.dispose();
  }

  @override
  bool get wantKeepAlive => true;
}

typedef RefreshViewStringBuilder = String Function(BuildContext context);
